home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / book / Chap17 / Text3D / Text3D.c next >
Encoding:
C/C++ Source or Header  |  1999-09-21  |  11.3 KB  |  435 lines

  1. // GLPalette.c
  2. // OpenGL SuperBible, Chapter 17
  3. // Program by Richard S. Wright Jr.
  4. // This program demonstrates creation and use of a 332 palette for OpenGL
  5. #include <windows.h>
  6. #include <gl\gl.h>
  7. #include <gl\glu.h>
  8.  
  9. // Palette Handle
  10. HPALETTE hPalette = NULL;
  11.  
  12.  
  13. static LPCTSTR lpszAppName = "Text3D";
  14. GLint nFontList;
  15.  
  16. // Light values and coordinates
  17. GLfloat  whiteLight[] = { 0.4f, 0.4f, 0.4f, 1.0f };
  18. GLfloat  diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
  19. GLfloat  specular[] = { 0.9f, 0.9f, 0.9f, 1.0f};
  20. GLfloat lightPos[] = { -100.0f, 200.0f, 50.0f, 1.0f };
  21.  
  22.  
  23. // Declaration for Window procedure
  24. LRESULT CALLBACK WndProc(    HWND     hWnd,
  25.                             UINT    message,
  26.                             WPARAM    wParam,
  27.                             LPARAM    lParam);
  28.  
  29. // Set Pixel Format function - forward declaration
  30. void SetDCPixelFormat(HDC hDC);
  31.  
  32.  
  33.  
  34. void ChangeSize(GLsizei w, GLsizei h)
  35.     {
  36.     GLfloat nRange = 100.0f;
  37.     GLfloat fAspect;
  38.  
  39.     // Prevent a divide by zero
  40.     if(h == 0)
  41.         h = 1;
  42.  
  43.     fAspect = (GLfloat)w/(GLfloat)h;
  44.  
  45.     // Set Viewport to window dimensions
  46.     glViewport(0, 0, w, h);
  47.  
  48.     glMatrixMode(GL_PROJECTION);
  49.  
  50.     // Reset coordinate system
  51.     glLoadIdentity();
  52.  
  53.     // Setup perspective for viewing
  54.     gluPerspective(17.5f,fAspect,1,300);
  55.  
  56.     // Viewing transformation
  57.     glMatrixMode(GL_MODELVIEW);
  58.     glLoadIdentity();
  59.     glTranslatef(-1.8f, 0.0f, -15.0f);
  60.     glRotatef(-20.0f, 0.0f, 1.0f,0.0f);
  61.  
  62.     glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
  63.     }
  64.  
  65.  
  66. void RenderScene(void)
  67.     {
  68.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  69.  
  70.     // Blue 3D Text
  71.     glColor3ub(0, 0, 255);
  72.  
  73.     glPushMatrix();
  74.     glListBase(nFontList);
  75.     glCallLists (6, GL_UNSIGNED_BYTE, "OpenGL");     
  76.     glPopMatrix();
  77.     }
  78.  
  79.  
  80. void SetupRC(HDC hDC)
  81.     {
  82.     // Setup the Font characteristics
  83.     HFONT hFont;
  84.     GLYPHMETRICSFLOAT agmf[128]; // Throw away
  85.     LOGFONT logfont;
  86.  
  87.     logfont.lfHeight = -10;
  88.     logfont.lfWidth = 0;
  89.     logfont.lfEscapement = 0;
  90.     logfont.lfOrientation = 0;
  91.     logfont.lfWeight = FW_BOLD;
  92.     logfont.lfItalic = FALSE;
  93.     logfont.lfUnderline = FALSE;
  94.     logfont.lfStrikeOut = FALSE;
  95.     logfont.lfCharSet = ANSI_CHARSET;
  96.     logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
  97.     logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  98.     logfont.lfQuality = DEFAULT_QUALITY;
  99.     logfont.lfPitchAndFamily = DEFAULT_PITCH;
  100.     strcpy(logfont.lfFaceName,"Arial");
  101.  
  102.     // Create the font and display list
  103.     hFont = CreateFontIndirect(&logfont);
  104.     SelectObject (hDC, hFont); 
  105.  
  106.     
  107.     //create display lists for glyphs 0 through 128 with 0.1 extrusion 
  108.     // and default deviation. The display list numbering starts at 1000 
  109.     // (it could be any number). 
  110.     nFontList = glGenLists(128);
  111.     wglUseFontOutlines(hDC, 0, 128, nFontList, 0.0f, 0.5f, 
  112.                 WGL_FONT_POLYGONS, agmf); 
  113.  
  114.     DeleteObject(hFont);
  115.  
  116.     glEnable(GL_DEPTH_TEST);    // Hidden surface removal
  117.     glEnable(GL_COLOR_MATERIAL);
  118.  
  119.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
  120.  
  121.     glEnable(GL_LIGHTING);
  122.     glLightfv(GL_LIGHT0,GL_AMBIENT,whiteLight);
  123.     glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
  124.     glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
  125.     glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
  126.     glEnable(GL_LIGHT0);
  127.  
  128.  
  129.     glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  130.     glMaterialfv(GL_FRONT, GL_SPECULAR,specular);
  131.     glMateriali(GL_FRONT,GL_SHININESS,128);
  132.     }
  133.  
  134.  
  135. // If necessary, creates a 3-3-2 palette for the device context listed.
  136. HPALETTE GetOpenGLPalette(HDC hDC)
  137.     {
  138.     HPALETTE hRetPal = NULL;    // Handle to palette to be created
  139.     PIXELFORMATDESCRIPTOR pfd;    // Pixel Format Descriptor
  140.     LOGPALETTE *pPal;            // Pointer to memory for logical palette
  141.     int nPixelFormat;            // Pixel format index
  142.     int nColors;                // Number of entries in palette
  143.     int i;                        // Counting variable
  144.     BYTE RedRange,GreenRange,BlueRange;
  145.                                 // Range for each color entry (7,7,and 3)
  146.  
  147.  
  148.     // Get the pixel format index and retrieve the pixel format description
  149.     nPixelFormat = GetPixelFormat(hDC);
  150.     DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  151.  
  152.     // Does this pixel format require a palette?  If not, do not create a
  153.     // palette and just return NULL
  154.     if(!(pfd.dwFlags & PFD_NEED_PALETTE))
  155.         return NULL;
  156.  
  157.     // Number of entries in palette.  8 bits yeilds 256 entries
  158.     nColors = 1 << pfd.cColorBits;    
  159.  
  160.     // Allocate space for a logical palette structure plus all the palette entries
  161.     pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));
  162.  
  163.     // Fill in palette header 
  164.     pPal->palVersion = 0x300;        // Windows 3.0
  165.     pPal->palNumEntries = nColors; // table size
  166.  
  167.     // Build mask of all 1's.  This creates a number represented by having
  168.     // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
  169.     // pfd.cBlueBits.  
  170.     RedRange = (1 << pfd.cRedBits) -1;
  171.     GreenRange = (1 << pfd.cGreenBits) - 1;
  172.     BlueRange = (1 << pfd.cBlueBits) -1;
  173.  
  174.     // Loop through all the palette entries
  175.     for(i = 0; i < nColors; i++)
  176.         {
  177.         // Fill in the 8-bit equivalents for each component
  178.         pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
  179.         pPal->palPalEntry[i].peRed = (unsigned char)(
  180.             (double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
  181.  
  182.         pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
  183.         pPal->palPalEntry[i].peGreen = (unsigned char)(
  184.             (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
  185.  
  186.         pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
  187.         pPal->palPalEntry[i].peBlue = (unsigned char)(
  188.             (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
  189.  
  190.         pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
  191.         }
  192.         
  193.  
  194.     // Create the palette
  195.     hRetPal = CreatePalette(pPal);
  196.  
  197.     // Go ahead and select and realize the palette for this device context
  198.     SelectPalette(hDC,hRetPal,FALSE);
  199.     RealizePalette(hDC);
  200.  
  201.     // Free the memory used for the logical palette structure
  202.     free(pPal);
  203.  
  204.     // Return the handle to the new palette
  205.     return hRetPal;
  206.     }
  207.  
  208.  
  209. // Select the pixel format for a given device context
  210. void SetDCPixelFormat(HDC hDC)
  211.     {
  212.     int nPixelFormat;
  213.  
  214.     static PIXELFORMATDESCRIPTOR pfd = {
  215.         sizeof(PIXELFORMATDESCRIPTOR),    // Size of this structure
  216.         1,                                // Version of this structure    
  217.         PFD_DRAW_TO_WINDOW |            // Draw to Window (not to bitmap)
  218.         PFD_SUPPORT_OPENGL |            // Support OpenGL calls in window
  219.         PFD_DOUBLEBUFFER,                // Double buffered mode
  220.         PFD_TYPE_RGBA,                    // RGBA Color mode
  221.         32,                                // Want 32 bit color
  222.         0,0,0,0,0,0,                    // Not used to select mode
  223.         0,0,                            // Not used to select mode
  224.         0,0,0,0,0,                        // Not used to select mode
  225.         16,                                // Size of depth buffer
  226.         0,                                // Not used to select mode
  227.         0,                                // Not used to select mode
  228.         0,                                // Draw in main plane
  229.         0,                                // Not used to select mode
  230.         0,0,0 };                        // Not used to select mode
  231.  
  232.     // Choose a pixel format that best matches that described in pfd
  233.     nPixelFormat = ChoosePixelFormat(hDC, &pfd);
  234.  
  235.     // Set the pixel format for the device context
  236.     SetPixelFormat(hDC, nPixelFormat, &pfd);
  237.     }
  238.  
  239.  
  240.  
  241. // Entry point of all Windows programs
  242. int APIENTRY WinMain(    HINSTANCE     hInstance,
  243.                         HINSTANCE     hPrevInstance,
  244.                         LPSTR         lpCmdLine,
  245.                         int            nCmdShow)
  246.     {
  247.     MSG            msg;        // Windows message structure
  248.     WNDCLASS    wc;            // Windows class structure
  249.     HWND        hWnd;        // Storeage for window handle
  250.  
  251.  
  252.     // Register Window style
  253.     wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  254.     wc.lpfnWndProc        = (WNDPROC) WndProc;
  255.     wc.cbClsExtra        = 0;
  256.     wc.cbWndExtra        = 0;
  257.     wc.hInstance         = hInstance;
  258.     wc.hIcon            = NULL;
  259.     wc.hCursor            = LoadCursor(NULL, IDC_ARROW);
  260.     
  261.     // No need for background brush for OpenGL window
  262.     wc.hbrBackground    = NULL;        
  263.     
  264.     wc.lpszMenuName        = NULL;
  265.     wc.lpszClassName    = lpszAppName;
  266.  
  267.     // Register the window class
  268.     if(RegisterClass(&wc) == 0)
  269.         return FALSE;
  270.  
  271.  
  272.     // Create the main application window
  273.     hWnd = CreateWindow(
  274.                 lpszAppName,
  275.                 lpszAppName,
  276.                 
  277.                 // OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS
  278.                 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  279.     
  280.                 // Window position and size
  281.                 100, 100,
  282.                 250, 250,
  283.                 NULL,
  284.                 NULL,
  285.                 hInstance,
  286.                 NULL);
  287.  
  288.     // If window was not created, quit
  289.     if(hWnd == NULL)
  290.         return FALSE;
  291.  
  292.  
  293.     // Display the window
  294.     ShowWindow(hWnd,SW_SHOW);
  295.     UpdateWindow(hWnd);
  296.  
  297.     // Process application messages until the application closes
  298.     while( GetMessage(&msg, NULL, 0, 0))
  299.         {
  300.         TranslateMessage(&msg);
  301.         DispatchMessage(&msg);
  302.         }
  303.  
  304.     return msg.wParam;
  305.     }
  306.  
  307.  
  308.  
  309. // Window procedure, handles all messages for this program
  310. LRESULT CALLBACK WndProc(    HWND     hWnd,
  311.                             UINT    message,
  312.                             WPARAM    wParam,
  313.                             LPARAM    lParam)
  314.     {
  315.     static HGLRC hRC;        // Permenant Rendering context
  316.     static HDC hDC;            // Private GDI Device context
  317.  
  318.     switch (message)
  319.            {
  320.         // Window creation, setup for OpenGL
  321.         case WM_CREATE:
  322.             // Store the device context
  323.             hDC = GetDC(hWnd);        
  324.  
  325.             // Select the pixel format
  326.             SetDCPixelFormat(hDC);        
  327.  
  328.             // Create the rendering context and make it current
  329.             hRC = wglCreateContext(hDC);
  330.             wglMakeCurrent(hDC, hRC);
  331.  
  332.             // Create the palette
  333.             hPalette = GetOpenGLPalette(hDC);
  334.  
  335.             SetupRC(hDC);
  336.  
  337.             break;
  338.  
  339.         // Window is being destroyed, cleanup
  340.         case WM_DESTROY:
  341.             // Kill the timer that we created
  342.             KillTimer(hWnd,101);
  343.  
  344.             glDeleteLists(nFontList, 128);
  345.  
  346.             // Deselect the current rendering context and delete it
  347.             wglMakeCurrent(hDC,NULL);
  348.             wglDeleteContext(hRC);
  349.  
  350.             // Delete the palette
  351.             if(hPalette != NULL)
  352.                 DeleteObject(hPalette);
  353.  
  354.             // Tell the application to terminate after the window
  355.             // is gone.
  356.             PostQuitMessage(0);
  357.             break;
  358.  
  359.         // Window is resized.
  360.         case WM_SIZE:
  361.             // Call our function which modifies the clipping
  362.             // volume and viewport
  363.             ChangeSize(LOWORD(lParam), HIWORD(lParam));
  364.             break;
  365.  
  366.         // The painting function.  This message sent by Windows 
  367.         // whenever the screen needs updating.
  368.         case WM_PAINT:
  369.             {
  370.             // Call OpenGL drawing code
  371.             RenderScene();
  372.  
  373.             // Call function to swap the buffers
  374.             SwapBuffers(hDC);
  375.  
  376.             ValidateRect(hWnd,NULL);
  377.             }
  378.             break;
  379.  
  380.  
  381.         // Windows is telling the application that it may modify
  382.         // the system palette.  This message in essance asks the 
  383.         // application for a new palette.
  384.         case WM_QUERYNEWPALETTE:
  385.             // If the palette was created.
  386.             if(hPalette)
  387.                 {
  388.                 int nRet;
  389.  
  390.                 // Selects the palette into the current device context
  391.                 SelectPalette(hDC, hPalette, FALSE);
  392.  
  393.                 // Map entries from the currently selected palette to
  394.                 // the system palette.  The return value is the number 
  395.                 // of palette entries modified.
  396.                 nRet = RealizePalette(hDC);
  397.  
  398.                 // Repaint, forces remap of palette in current window
  399.                 InvalidateRect(hWnd,NULL,FALSE);
  400.  
  401.                 return nRet;
  402.                 }
  403.             break;
  404.  
  405.     
  406.         // This window may set the palette, even though it is not the 
  407.         // currently active window.
  408.         case WM_PALETTECHANGED:
  409.             // Don't do anything if the palette does not exist, or if
  410.             // this is the window that changed the palette.
  411.             if((hPalette != NULL) && ((HWND)wParam != hWnd))
  412.                 {
  413.                 // Select the palette into the device context
  414.                 SelectPalette(hDC,hPalette,FALSE);
  415.  
  416.                 // Map entries to system palette
  417.                 RealizePalette(hDC);
  418.                 
  419.                 // Remap the current colors to the newly realized palette
  420.                 UpdateColors(hDC);
  421.                 return 0;
  422.                 }
  423.             break;
  424.  
  425.  
  426.         default:   // Passes it on if unproccessed
  427.             return (DefWindowProc(hWnd, message, wParam, lParam));
  428.  
  429.         }
  430.  
  431.     return (0L);
  432.     }
  433.  
  434.  
  435.